package com.scap.dfs.dao.impl;

import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Transaction;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.scap.dfs.dao.DepartmentDao;
import com.scap.dfs.model.Department;
import com.scap.dfs.model.DepartmentPK;

@Repository
public class DepartmentDaoImpl implements DepartmentDao {
	
	final static Logger logger = Logger.getLogger(DepartmentDaoImpl.class);
	
	@Autowired
	SessionFactory sessionFactory;

	
	public boolean insert(Department department){
		
		DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
		Date date = new Date();
		department.setUpdateTime(dateFormat.format(date));
		dateFormat = new SimpleDateFormat("yyyyMMdd");
		department.setUpdateDate(dateFormat.format(date));
		
		Session session = sessionFactory.openSession();
		Transaction tx = session.beginTransaction();
		try{
			Serializable result = null;
			result = session.save(department);
			System.out.println("Result form add departmenr : "+result);
			tx.commit();
		}
		catch(Exception e){
			logger.error(e);
			tx.rollback();
			return false;
		}
		finally{
			session.flush();
			session.clear();
			session.close();
		}
		return true;
	}


	@Override
	public boolean update(Department d1) {
		Session session = sessionFactory.openSession();
		Transaction tx = session.beginTransaction();
		
		try{
			//1.First way - Dynamic way
//			Department d2 = (Department) session.get(Department.class, d1.getId());
//			d2.setActive(d1.getActive()!=null?d1.getActive():d2.getActive());
//			d2.setDefaultLocationCode(d1.getDefaultLocationCode()!=null?d1.getDefaultLocationCode():d2.getDefaultLocationCode());
//			d2.setDescription(d1.getDescription()!=null?d1.getDescription():d2.getDescription());
//			d2.setGlCode(d1.getGlCode()!=null?d1.getGlCode():d2.getGlCode());
//			d2.setHospitalUnitCode(d1.getHospitalUnitCode()!=null?d1.getHospitalUnitCode():d2.getHospitalUnitCode());
//			d2.setUserId(d1.getUserId()!=null?d1.getUserId():d2.getUserId());
//			DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
//			Date date = new Date();
//			d2.setUpdateTime(dateFormat.format(date));
//			dateFormat = new SimpleDateFormat("yyyyMMdd");
//			d2.setUpdateDate(dateFormat.format(date));
//			session.update(d2);
			
			//2.Second way performance way
			System.out.println("d1.pk : "+d1.getId().toString());
			
			String hql = " update Department set ";
			if(d1.getActive()!=null)hql+=" active = '"+ d1.getActive()+"' ,";
			if(d1.getDefaultLocationCode()!=null)hql+=" defaultLocationCode = '"+d1.getDefaultLocationCode()+"' ,";
			if(d1.getDescription()!=null)hql+=" description = '"+d1.getDescription()+"' ,";
			if(d1.getGlCode()!=null)hql+=" glCode = '"+d1.getGlCode()+"' ,";
			if(d1.getHospitalUnitCode()!=null)hql+=" hospitalUnitCode = '"+d1.getHospitalUnitCode()+"' ,";
			if(d1.getUserId()!=null)hql+=" userId = '"+d1.getUserId()+"' ,";
			hql = hql.substring(0, hql.length()-2)+" ";
			hql+=" where id.code = '"+d1.getId().getCode()+"' and  id.hospitalCode = '"+d1.getId().getHospitalCode()+"'  ";			
			Query query = session.createQuery(hql);
			int result = query.executeUpdate();
			System.out.println("Result from update department : "+result);
			
			tx.commit();
		}
		catch(Exception e){
			logger.error(e);
			tx.rollback();
			return false;
		}
		finally{
			session.flush();
			session.clear();
			session.close();
		}
		return true;
	}


	@Override
	public boolean delete(DepartmentPK pk) {
		Department department = new Department();
		department.setId(pk);
		Session session = sessionFactory.openSession();
		Transaction tx = session.beginTransaction();
		try{
			session.delete(department);
			tx.commit();
		}
		catch(Exception e){
			logger.error(e);
			tx.rollback();
			return false;
		}
		finally{
			session.flush();
			session.clear();
			session.close();
		}
		return true;
	}


	@Override
	public Department findById(DepartmentPK pk) {
		Session session = sessionFactory.openSession();
		Department department = null;
		try{
			department = (Department) session.get(Department.class,pk);
		}
		catch(Exception e){
			logger.error(e);
			return null;
		}
		finally{
			session.flush();
			session.clear();
			session.close();
		}
		return department;
	}


	@Override
	public List getList() {
		Session session = sessionFactory.openSession();
		List<Department> departments = null;
		try{
			//1. First way
//			Criteria cr = session.createCriteria(Department.class);
//			cr.addOrder(Order.asc("id.code"));
//			cr.setFirstResult(0);//0 = first element
//			cr.setMaxResults(100)
//			departments = cr.list();
			//2. Second way
			departments = session.createQuery("from Department d order by id.code").list();
			
		}
		catch(Exception e){
			logger.error(e);
			return null;
		}
		finally{
			session.flush();
			session.clear();
			session.close();
		}
		return departments;
	}


	@Override
	public List getListPerPage(int amount, int page,String orderByColumnName,String ascOrDesc) {
		Session session = sessionFactory.openSession();
		int firstElement = amount*(page-1);
		List<Department> departments = null;
		
		try{//id.code
			departments = session.createQuery("from Department d order by "+orderByColumnName+" "+ascOrDesc+" ")
//					.setString("orderBy", orderByColumnName).setString("ascOrDesc", ascOrDesc)
					.setFirstResult(firstElement).setMaxResults(amount).list();
		}
		catch(Exception e){
			logger.error(e);
			return null;
		}
		finally{
			session.flush();
			session.clear();
			session.close();
		}
		return departments;
	}


	@Override
	public List findByAttribute(Department department) {
		Session session = sessionFactory.openSession();
		List departments = null;
		//1. First way
		Criteria cr = session.createCriteria(Department.class);
		if(department.getActive()!=null)cr.add(Restrictions.like("active",department.getActive()));
		if(department.getDefaultLocationCode()!=null)cr.add(Restrictions.like("defaultLocationCode", department.getDefaultLocationCode()));
		if(department.getDescription()!=null)cr.add(Restrictions.like("description",department.getDescription()));
		if(department.getGlCode()!=null)cr.add(Restrictions.like("glCode",department.getGlCode()));
		if(department.getHospitalUnitCode()!=null)cr.add(Restrictions.like("hospitalUnitCode",department.getHospitalUnitCode()));
		if(department.getUpdateDate()!=null)cr.add(Restrictions.like("updateDate",department.getUpdateDate()));
		if(department.getUpdateTime()!=null)cr.add(Restrictions.like("updateTime",department.getUpdateTime()));
		if(department.getUserId()!=null)cr.add(Restrictions.like("userId",department.getUserId()));
		if(department.getId().getCode()!=null)cr.add(Restrictions.like("id.code",department.getId().getCode()));
		if(department.getId().getHospitalCode()!=null)cr.add(Restrictions.like("id.hospitalCode",department.getId().getHospitalCode()));
		
		cr.addOrder(Order.asc("id.code"));
		
		departments = cr.list();
		
		return departments;
	}


	@Override
	public List findByAttributePerPage(Department department, int amount,
			int page,String orderByColumnName,String ascOrDesc) {
		
		Session session = sessionFactory.openSession();
		List departments = null;
		//1. First way
		Criteria cr = session.createCriteria(Department.class);
		if(department.getActive()!=null)cr.add(Restrictions.like("active",department.getActive()));
		if(department.getDefaultLocationCode()!=null)cr.add(Restrictions.like("defaultLocationCode", department.getDefaultLocationCode()));
		if(department.getDescription()!=null)cr.add(Restrictions.like("description",department.getDescription()));
		if(department.getGlCode()!=null)cr.add(Restrictions.like("glCode",department.getGlCode()));
		if(department.getHospitalUnitCode()!=null)cr.add(Restrictions.like("hospitalUnitCode",department.getHospitalUnitCode()));
		if(department.getUpdateDate()!=null)cr.add(Restrictions.like("updateDate",department.getUpdateDate()));
		if(department.getUpdateTime()!=null)cr.add(Restrictions.like("updateTime",department.getUpdateTime()));
		if(department.getUserId()!=null)cr.add(Restrictions.like("userId",department.getUserId()));
		if(department.getId().getCode()!=null)cr.add(Restrictions.like("id.code",department.getId().getCode()));
		if(department.getId().getHospitalCode()!=null)cr.add(Restrictions.like("id.hospitalCode",department.getId().getHospitalCode()));
		
		if(ascOrDesc.equals("desc")||ascOrDesc=="desc"){
			cr.addOrder(Order.desc(orderByColumnName));
		}
		else{
			cr.addOrder(Order.asc(orderByColumnName));
		}
		int firstElement = amount*(page-1);
		cr.setFirstResult(firstElement);
		cr.setMaxResults(amount);
		departments = cr.list();
		
		return departments;
		
	}

}
